#pragma once

#include "type_traits.hpp"
namespace cpp
{
	struct none_t { constexpr explicit none_t() {} };
	constexpr bool operator==(none_t, none_t) { return true; }
	constexpr bool operator!=(none_t, none_t) { return false; }
	constexpr bool operator<(none_t, none_t) { return false; }
	constexpr bool operator<=(none_t, none_t) { return true; }
	constexpr bool operator>(none_t, none_t) { return false; }
	constexpr bool operator>=(none_t, none_t) { return true; }


#if 0
	// Comparison with none_t
	template < Nullable C >
	bool operator==(none_t, C const& x) noexcept { return !x.has_value(); }
	template < Nullable C >
	bool operator==(C const& x, none_t) noexcept { return !x.has_value(); }
	template < Nullable C >
	bool operator!=(none_t, C const& x) noexcept { return x.has_value(); }
	template < Nullable C >
	bool operator!=(C const& x, none_t) noexcept { return x.has_value(); }

	template < StrictWeaklyOrderedNullable C >
	bool operator<(none_t, C const& x) { return x.has_value(); }

	template < StrictWeaklyOrderedNullable C >
	bool operator<(C const& x, none_t{ return false; }

				   template < StrictWeaklyOrderedNullable C >
	bool operator<=(none_t, C const& x) { return true; }

	template < StrictWeaklyOrderedNullable C >
	bool operator<=(C const& x, none_t{ return !x.has_value(); }

					template < StrictWeaklyOrderedNullable C >
	bool operator>(none_t, C const& x) { return false; }

	template < StrictWeaklyOrderedNullable C >
	bool operator>(C const& x, none_t){ return x.has_value(); }
	template < StrictWeaklyOrderedNullable C >
	bool operator>=(none_t, C const& x) { return !x.has_value(); }
	template < StrictWeaklyOrderedNullable C >
	bool operator>=(C const& x, none_t){ return true; }

#endif

	constexpr none_t none() noexcept{ return none_t{}; }

	template <class T>
	struct nullable_traits;

	template <class T>
	struct nullable_traits<T*>
	{
		static constexpr nullptr_t none() noexcept { return nullptr; }
	};

	template <class TC>
	constexpr auto none() noexcept -> decltype(nullable_traits<TC>::none());


}
